import {NodeA,ASTree} from './arktsAST';
import {CFG,statement,conditionStatement,switchStatement} from './cfg';
import {Edge,Graph} from './graph';
import {FDT} from './fdt';
import {CDG,CDGGEN} from './cdg';
import * as fs from 'fs';

// let fileContent = fs.readFileSync(process.cwd() + '/src/testfile.ts', 'utf8');
// let ast:ASTree=new ASTree(fileContent);
// ast.buildTree()
// let cfg:CFG=new CFG(ast.root,"testfile");

let fileContent = fs.readFileSync('t.ts', 'utf8');
let ast:ASTree=new ASTree(fileContent);
ast.buildTree()
let cfg:CFG=new CFG(ast.root,"main");
let stmArray:statement[]=[];
function cfg2Array(stm:statement){
    if(stm.walked)
        return;
    stm.walked=true;
    stm.index=stmArray.length;
    stmArray.push(stm);
    if(stm.type=="ifStatement"||stm.type=="loopStatement"||stm.type=="catchOrNot"){
        let cstm=stm as conditionStatement;
        if(cstm.nextT==null||cstm.nextF==null){
            console.log("ifnext error");
            process.exit();
        }
        cfg2Array(cstm.nextF);
        cfg2Array(cstm.nextT);
    }
    else if(stm.type=="switchStatement"){
        let sstm=stm as switchStatement;
        for(let ss of sstm.nexts){
            cfg2Array(ss);
        }
    }
    else{
        if(stm.next!=null)
            cfg2Array(stm.next);
    }
}
cfg2Array(cfg.entry);
cfg.resetWalked(cfg.entry);

let graph = new CDGGEN(stmArray.length,0,stmArray.length-1);

function cfgAddEdge(stm:statement){
    if(stm.walked)
        return;
    stm.walked=true;
    if(stm.type=="ifStatement"||stm.type=="loopStatement"||stm.type=="catchOrNot"){
        let cstm=stm as conditionStatement;
        if(cstm.nextT==null||cstm.nextF==null){
            console.log("ifnext error");
            process.exit();
        }
        graph.addEdge(cstm.index,cstm.nextF.index)
        graph.addEdge(cstm.index,cstm.nextT.index)
        cfgAddEdge(cstm.nextF);
        cfgAddEdge(cstm.nextT);
    }
    else if(stm.type=="switchStatement"){
        let sstm=stm as switchStatement;
        for(let ss of sstm.nexts){
            graph.addEdge(sstm.index,ss.index)
            cfgAddEdge(ss);
        }
    }
    else{
        if(stm.next!=null){
            graph.addEdge(stm.index,stm.next.index)
            cfgAddEdge(stm.next);
        }
    }
}
cfgAddEdge(cfg.entry);
cfg.resetWalked(cfg.entry);

/*
graph.addEdge(1,2);graph.addEdge(1,8);graph.addEdge(1,11);graph.addEdge(2,3);graph.addEdge(2,6);graph.addEdge(3,4);
graph.addEdge(4,5);graph.addEdge(5,1);graph.addEdge(5,4);graph.addEdge(6,7);graph.addEdge(6,4);graph.addEdge(7,4);
graph.addEdge(8,11);graph.addEdge(8,12);graph.addEdge(8,9);graph.addEdge(9,10);graph.addEdge(10,9);graph.addEdge(10,5);
graph.addEdge(11,12);graph.addEdge(12,13);graph.addEdge(13,10);
*/

// graph.addEdge(1,2);
// graph.addEdge(2,3);
// graph.addEdge(2,4);
// graph.addEdge(3,5);
// graph.addEdge(4,5);
// graph.addEdge(5,6);

graph.init();
let cdg:CDG = graph.getCDG();
console.log(cdg);
